home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1 / Nebula One.iso / Mail / pine3.92 / pico / buffer.c < prev    next >
C/C++ Source or Header  |  1996-03-14  |  10KB  |  371 lines

  1. #if    !defined(lint) && !defined(DOS)
  2. static char rcsid[] = "$Id: buffer.c,v 4.10 1996/03/15 07:41:11 hubert Exp $";
  3. #endif
  4. /*
  5.  * Program:    Buffer management routines
  6.  *
  7.  *
  8.  * Michael Seibel
  9.  * Networks and Distributed Computing
  10.  * Computing and Communications
  11.  * University of Washington
  12.  * Administration Builiding, AG-44
  13.  * Seattle, Washington, 98195, USA
  14.  * Internet: mikes@cac.washington.edu
  15.  *
  16.  * Please address all bugs and comments to "pine-bugs@cac.washington.edu"
  17.  *
  18.  *
  19.  * Pine and Pico are registered trademarks of the University of Washington.
  20.  * No commercial use of these trademarks may be made without prior written
  21.  * permission of the University of Washington.
  22.  * 
  23.  * Pine, Pico, and Pilot software and its included text are Copyright
  24.  * 1989-1996 by the University of Washington.
  25.  * 
  26.  * The full text of our legal notices is contained in the file called
  27.  * CPYRIGHT, included with this distribution.
  28.  *
  29.  */
  30. /*
  31.  * Buffer management.
  32.  * Some of the functions are internal,
  33.  * and some are actually attached to user
  34.  * keys. Like everyone else, they set hints
  35.  * for the display system.
  36.  */
  37. #include        <stdio.h>
  38. #include    "osdep.h"
  39. #include        "pico.h"
  40. #include    "estruct.h"
  41. #include        "edef.h"
  42.  
  43. #ifdef    ANSI
  44. int sgetline(char **, int *, char *, int);
  45. #else
  46. int sgetline();
  47. #endif
  48.  
  49.  
  50. /*
  51.  * Look through the list of
  52.  * buffers. Return TRUE if there
  53.  * are any changed buffers. Buffers
  54.  * that hold magic internal stuff are
  55.  * not considered; who cares if the
  56.  * list of buffer names is hacked.
  57.  * Return FALSE if no buffers
  58.  * have been changed.
  59.  */
  60. anycb()
  61. {
  62.         register BUFFER *bp;
  63.  
  64.         bp = bheadp;
  65.         while (bp != NULL) {
  66.                 if ((bp->b_flag&BFTEMP)==0 && (bp->b_flag&BFCHG)!=0)
  67.                         return (TRUE);
  68.                 bp = bp->b_bufp;
  69.         }
  70.         return (FALSE);
  71. }
  72.  
  73. /*
  74.  * Find a buffer, by name. Return a pointer
  75.  * to the BUFFER structure associated with it. If
  76.  * the named buffer is found, but is a TEMP buffer (like
  77.  * the buffer list) conplain. If the buffer is not found
  78.  * and the "cflag" is TRUE, create it. The "bflag" is
  79.  * the settings for the flags in in buffer.
  80.  */
  81. BUFFER  *
  82. bfind(bname, cflag, bflag)
  83. register char   *bname;
  84. {
  85.         register BUFFER *bp;
  86.     register BUFFER *sb;    /* buffer to insert after */
  87.         register LINE   *lp;
  88.  
  89.         bp = bheadp;
  90.         while (bp != NULL) {
  91.                 if (strcmp(bname, bp->b_bname) == 0) {
  92.                         if ((bp->b_flag&BFTEMP) != 0) {
  93.                                 mlwrite("Cannot select builtin buffer");
  94.                                 return (NULL);
  95.                         }
  96.                         return (bp);
  97.                 }
  98.                 bp = bp->b_bufp;
  99.         }
  100.         if (cflag != FALSE) {
  101.                 if ((bp=(BUFFER *)malloc(sizeof(BUFFER))) == NULL)
  102.                         return (NULL);
  103.                 if ((lp=lalloc(0)) == NULL) {
  104.                         free((char *) bp);
  105.                         return (NULL);
  106.                 }
  107.         /* find the place in the list to insert this buffer */
  108.         if (bheadp == NULL || strcmp(bheadp->b_bname, bname) > 0) {
  109.             /* insert at the begining */
  110.                     bp->b_bufp = bheadp;
  111.                     bheadp = bp;
  112.             } else {
  113.             sb = bheadp;
  114.             while (sb->b_bufp != NULL) {
  115.                 if (strcmp(sb->b_bufp->b_bname, bname) > 0)
  116.                     break;
  117.                 sb = sb->b_bufp;
  118.             }
  119.  
  120.             /* and insert it */
  121.                    bp->b_bufp = sb->b_bufp;
  122.                 sb->b_bufp = bp;
  123.                }
  124.  
  125.         /* and set up the other buffer fields */
  126.         bp->b_active = TRUE;
  127.                 bp->b_dotp  = lp;
  128.                 bp->b_doto  = 0;
  129.                 bp->b_markp = NULL;
  130.                 bp->b_marko = 0;
  131.                 bp->b_flag  = bflag;
  132.         bp->b_mode  = gmode;
  133.                 bp->b_nwnd  = 0;
  134.                 bp->b_linep = lp;
  135.                 strcpy(bp->b_fname, "");
  136.                 strcpy(bp->b_bname, bname);
  137.                 lp->l_fp = lp;
  138.                 lp->l_bp = lp;
  139.         }
  140.         return (bp);
  141. }
  142.  
  143. /*
  144.  * This routine blows away all of the text
  145.  * in a buffer. If the buffer is marked as changed
  146.  * then we ask if it is ok to blow it away; this is
  147.  * to save the user the grief of losing text. The
  148.  * window chain is nearly always wrong if this gets
  149.  * called; the caller must arrange for the updates
  150.  * that are required. Return TRUE if everything
  151.  * looks good.
  152.  */
  153. bclear(bp)
  154. register BUFFER *bp;
  155. {
  156.         register LINE   *lp;
  157.         register int    s = FALSE;
  158.  
  159.     if(Pmaster){
  160.         if ((bp->b_flag&BFTEMP) == 0     /* Not scratch buffer.  */
  161.         && (bp->b_flag&BFCHG) != 0){    /* Something changed    */
  162.         emlwrite("buffer lines not freed.");
  163.         return (s);
  164.         }
  165.     }
  166.     else{
  167.         if ((bp->b_flag&BFTEMP) == 0    /* Not scratch buffer.  */
  168.         && (bp->b_flag&BFCHG) != 0    /* Something changed    */
  169.         && (s=mlyesno("Discard changes", -1)) != TRUE){
  170.         return (s);
  171.         }
  172.     }
  173.  
  174.         bp->b_flag  &= ~BFCHG;                  /* Not changed          */
  175.         while ((lp=lforw(bp->b_linep)) != bp->b_linep)
  176.                 lfree(lp);
  177.         bp->b_dotp  = bp->b_linep;              /* Fix "."              */
  178.         bp->b_doto  = 0;
  179.         bp->b_markp = NULL;                     /* Invalidate "mark"    */
  180.         bp->b_marko = 0;
  181.         return (TRUE);
  182. }
  183.  
  184.  
  185. /*
  186.  * packbuf - will pack up the main buffer in the buffer provided 
  187.  *           to be returned to the program that called pico.
  188.  *         if need be, allocate memory for the new message. 
  189.  *           will also free the memory associated with the editor
  190.  *           buffer, by calling zotedit.
  191.  */
  192. packbuf(buf, blen, lcrlf)
  193. char    **buf;
  194. int    *blen;
  195. int    lcrlf;                /* EOLs are local or CRLF */
  196. {
  197.     register int    s;
  198.     register int    i = 0;
  199.     register LINE   *lp;
  200.     register int    retval = 0;
  201.     register char   *bufp;
  202.     register char   *eobuf;
  203.  
  204.     if(anycb() != FALSE){
  205.  
  206.         lp = lforw(curbp->b_linep);
  207.         do{                    /* how many chars? */
  208.             i += llength(lp);
  209.         /*
  210.          * add extra for new lines to be inserted later
  211.          */
  212.         i += 2;
  213.         lp = lforw(lp);
  214.         }
  215.         while(lp != curbp->b_linep);
  216.  
  217.         if(i > *blen){                /* new buffer ? */
  218.             /*
  219.              * don't forget to add one for the null terminator!!!
  220.              */
  221.         if((bufp = (char *)malloc((i+1)*sizeof(char))) == NULL){
  222.                     zotedit();            /* bag it! */
  223.             return(COMP_FAILED);
  224.         }
  225.             free(*buf);
  226.         *buf = bufp;
  227.         *blen = i;
  228.         }
  229.         else{
  230.             bufp = *buf;
  231.         }
  232.     
  233.         eobuf = bufp + *blen;
  234.         lp = lforw(curbp->b_linep);             /* First line.          */
  235.         do {
  236.         for (i = 0; i < llength(lp); i++){    /* copy into buffer */
  237.             if((bufp+1) < eobuf){
  238.             *bufp++ = (lp->l_text[i].c & 0xFF);
  239.             }
  240.             else{
  241.             /*
  242.              * the idea is to malloc enough space for the new
  243.              * buffer...
  244.              */
  245.             *bufp = '\0';
  246.                     zotedit();
  247.             return(BUF_CHANGED|COMP_FAILED);
  248.             }
  249.         }
  250.         if(lcrlf){
  251.         *bufp++ = '\n';            /* EOLs use local convention */
  252.         }
  253.         else{
  254.         *bufp++ = 0x0D;            /* EOLs use net standard */
  255.         *bufp++ = 0x0A;
  256.         }
  257.             lp = lforw(lp);
  258.         }
  259.         while (lp != curbp->b_linep);
  260.     if(lcrlf)
  261.       *--bufp = '\0';
  262.     else
  263.       *bufp = '\0';
  264.         retval = BUF_CHANGED;
  265.     }
  266.  
  267.     zotedit();
  268.     return(retval);
  269. }
  270.  
  271.  
  272. /*
  273.  * readbuf - reads in a buffer.
  274.  */
  275. readbuf(buf)
  276. char    **buf;
  277. {
  278.         register LINE   *lp1;
  279.         register LINE   *lp2;
  280.         register BUFFER *bp;
  281.         register WINDOW *wp;
  282.         register int    i;
  283.         register int    s;
  284.         char   *sptr;          /* pointer into buffer string */
  285.         int        nbytes;
  286.         char            line[NLINE];
  287.     CELL            ac;
  288.  
  289.     bp = curbp;
  290.         bp->b_flag &= ~(BFTEMP|BFCHG);
  291.     sptr = *buf;
  292.     ac.a  = 0;
  293.  
  294.         while((s=sgetline(&sptr,&nbytes,line,NLINE)) == FIOSUC || s == FIOLNG){
  295.  
  296.                 if ((lp1=lalloc(nbytes)) == NULL) {
  297.                         s = FIOERR;             /* Keep message on the  */
  298.                         break;                  /* display.             */
  299.                 }
  300.                 lp2 = lback(curbp->b_linep);
  301.                 lp2->l_fp = lp1;
  302.                 lp1->l_fp = curbp->b_linep;
  303.                 lp1->l_bp = lp2;
  304.                 curbp->b_linep->l_bp = lp1;
  305.                 for (i=0; i<nbytes; ++i){
  306.             ac.c = line[i];
  307.             lputc(lp1, i, ac);
  308.         }
  309.         }
  310.  
  311.         for (wp=wheadp; wp!=NULL; wp=wp->w_wndp) {
  312.                 if (wp->w_bufp == curbp) {
  313.                         wheadp->w_linep = lforw(curbp->b_linep);
  314.                         wheadp->w_dotp  = lback(curbp->b_linep);
  315.                         wheadp->w_doto  = 0;
  316.                         wheadp->w_markp = NULL;
  317.                         wheadp->w_marko = 0;
  318.                         wheadp->w_flag |= WFHARD;
  319.                 }
  320.         }
  321.  
  322.     strcpy(bp->b_bname, "main");
  323.     strcpy(bp->b_fname, "");
  324.  
  325.     bp->b_dotp = bp->b_linep;
  326.     bp->b_doto = 0;
  327. }
  328.  
  329.  
  330. /*
  331.  * sgetline - copy characters from ibuf to obuf, ending at the first 
  332.  *            newline.  return with ibuf pointing to first char after
  333.  *            newline.
  334.  */
  335. sgetline(ibuf, nchars, obuf, blen)
  336. char    **ibuf;
  337. int    *nchars;
  338. char    *obuf;
  339. int    blen;
  340. {
  341.     register char     *len;
  342.     register char     *cbuf = *ibuf;
  343.     register char     *bufp = obuf;
  344.     register int     retval = FIOSUC;
  345. #define CR '\015'
  346. #define LF '\012'
  347.  
  348.     *nchars = 0;
  349.     if(*cbuf == '\0'){
  350.     retval = FIOEOF;
  351.     }
  352.     else{
  353.     len = obuf + blen;
  354.     while (*cbuf != CR && *cbuf != LF && *cbuf != '\0'){
  355.         if(bufp < len){
  356.         *bufp++ = *cbuf++;
  357.         (*nchars)++;
  358.         }
  359.         else{
  360.         *bufp = '\0';
  361.         retval = FIOLNG;
  362.         break;
  363.         }
  364.     }
  365.     }
  366.     *bufp = '\0';            /* end retured line */
  367.     *ibuf = (*cbuf == CR) ? ++cbuf : cbuf;
  368.     *ibuf = (*cbuf == LF) ? ++cbuf : cbuf;
  369.     return(retval);
  370. }
  371.